package org.dreamwork.cai.core;

import org.dreamwork.cai.ServiceNotFoundException;
import org.dreamwork.cai.srf.ServiceRouteFrame;

import java.rmi.RemoteException;

public interface IRemoteServices {
    /**
     * 根据给定的 {@code namespace} 和 {@code name} 来查找远程服务的 {@code 代理接口}.
     * @param namespace 远程服务的命名空间
     * @param name      服务名称
     * @return 远程服务的 {@code 代理接口}
     * @throws ServiceNotFoundException 若远程服务无效，则抛出该错误
     */
    Object lookup (String namespace, String name) throws ServiceNotFoundException;

    /**
     * 根据给定的 {@code namespace} 和 类型来查找远程服务的 {@code 代理接口}.
     * @param namespace 远程服务的命名空间
     * @param type      远程服务类型。这个类型必须在本地能够被加载
     * @param <T>       远程服务类型
     * @return 远程服务的 {@code 代理接口}
     * @throws ServiceNotFoundException 若远程服务无效，则抛出该错误
     */
    <T> T lookup (String namespace, Class<T> type) throws ServiceNotFoundException;

    /**
     * 注册一个 srf
     * @param frame 远程路由帧
     * @throws Exception 任何错误
     */
    void register (ServiceRouteFrame frame) throws Exception;

    /**
     * 从缓存中删除 SRF 对应的 Spring ApplicationContext
     * @param namespace SRF 的命名空间
     */
    void remove (String namespace);

    /**
     * 调用一个远程服务
     * @param namespace 远程 {@code SRF} 的命名空间
     * @param endpoint  远程 {@code SRI} 的 Endpoint
     * @param uuid      远程方法的 UUID
     * @param args      远程方法的参数表
     * @return 远程方法的返回结果
     * @throws ServiceNotFoundException 若由 {@code namespace/endpoint/uuid} 索引的远程方法不存在时抛出
     * @throws RemoteException 若在远程调用过程中有任何错误发生时抛出
     */
    Object call (String namespace, String endpoint, String uuid, Object... args) throws ServiceNotFoundException, RemoteException;
}